home *** CD-ROM | disk | FTP | other *** search
- #include "port.h"
- #include "sparse_int.h"
-
-
- /*
- * allocate a new col vector
- */
- sm_col *sm_col_alloc(void)
- {
- register sm_col *pcol;
-
- #ifdef FAST_AND_LOOSE
- if (sm_col_freelist == NIL(sm_col)) {
- pcol = ALLOC(sm_col, 1);
- } else {
- pcol = sm_col_freelist;
- sm_col_freelist = pcol->next_col;
- }
- #else
- pcol = ALLOC(sm_col, 1);
- #endif
-
- pcol->col_num = 0;
- pcol->length = 0;
- pcol->first_row = pcol->last_row = NIL(sm_element);
- pcol->next_col = pcol->prev_col = NIL(sm_col);
- pcol->flag = 0;
- pcol->user_word = NIL(char); /* for our user ... */
- return pcol;
- }
-
-
- /*
- * free a col vector -- for FAST_AND_LOOSE, this is real cheap for cols;
- * however, freeing a rowumn must still walk down the rowumn discarding
- * the elements one-by-one; that is the only use for the extra '-DCOLS'
- * compile flag ...
- */
- void sm_col_free(register sm_col *pcol)
- {
- #if defined(FAST_AND_LOOSE) && ! defined(COLS)
- if (pcol->first_row != NIL(sm_element)) {
- /* Add the linked list of col items to the free list */
- pcol->last_row->next_row = sm_element_freelist;
- sm_element_freelist = pcol->first_row;
- }
-
- /* Add the col to the free list of cols */
- pcol->next_col = sm_col_freelist;
- sm_col_freelist = pcol;
- #else
- register sm_element *p, *pnext;
-
- for(p = pcol->first_row; p != 0; p = pnext) {
- pnext = p->next_row;
- sm_element_free(p);
- }
- FREE(pcol);
- #endif
- }
-
-
- /*
- * duplicate an existing col
- */
- sm_col *sm_col_dup(register sm_col *pcol)
- {
- register sm_col *pnew;
- register sm_element *p;
-
- pnew = sm_col_alloc();
- for(p = pcol->first_row; p != 0; p = p->next_row) {
- (void) sm_col_insert(pnew, p->row_num);
- }
- return pnew;
- }
-
-
- /*
- * insert an element into a col vector
- */
- sm_element *sm_col_insert(register sm_col *pcol, register int row)
- {
- register sm_element *test, *element;
-
- /* get a new item, save its address */
- sm_element_alloc(element);
- test = element;
- sorted_insert(sm_element, pcol->first_row, pcol->last_row, pcol->length,
- next_row, prev_row, row_num, row, test);
-
- /* if item was not used, free it */
- if (element != test) {
- sm_element_free(element);
- }
-
- /* either way, return the current new value */
- return test;
- }
-
-
- /*
- * remove an element from a col vector
- */
- void sm_col_remove(register sm_col *pcol, register int row)
- {
- register sm_element *p;
-
- for(p = pcol->first_row; p != 0 && p->row_num < row; p = p->next_row)
- ;
- if (p != 0 && p->row_num == row) {
- dll_unlink(p, pcol->first_row, pcol->last_row,
- next_row, prev_row, pcol->length);
- sm_element_free(p);
- }
- }
-
-
- /*
- * find an element (if it is in the col vector)
- */
- sm_element *sm_col_find(sm_col *pcol, int row)
- {
- register sm_element *p;
-
- for(p = pcol->first_row; p != 0 && p->row_num < row; p = p->next_row)
- ;
- if (p != 0 && p->row_num == row) {
- return p;
- } else {
- return NIL(sm_element);
- }
- }
-
- /*
- * return 1 if col p2 contains col p1; 0 otherwise
- */
- int sm_col_contains(sm_col *p1, sm_col *p2)
- {
- register sm_element *q1, *q2;
-
- q1 = p1->first_row;
- q2 = p2->first_row;
- while (q1 != 0) {
- if (q2 == 0 || q1->row_num < q2->row_num) {
- return 0;
- } else if (q1->row_num == q2->row_num) {
- q1 = q1->next_row;
- q2 = q2->next_row;
- } else {
- q2 = q2->next_row;
- }
- }
- return 1;
- }
-
-
- /*
- * return 1 if col p1 and col p2 share an element in common
- */
- int sm_col_intersects(sm_col *p1, sm_col *p2)
- {
- register sm_element *q1, *q2;
-
- q1 = p1->first_row;
- q2 = p2->first_row;
- if (q1 == 0 || q2 == 0) return 0;
- for(;;) {
- if (q1->row_num < q2->row_num) {
- if ((q1 = q1->next_row) == 0) {
- return 0;
- }
- } else if (q1->row_num > q2->row_num) {
- if ((q2 = q2->next_row) == 0) {
- return 0;
- }
- } else {
- return 1;
- }
- }
- }
-
-
- /*
- * compare two cols, lexical ordering
- */
- int sm_col_compare(sm_col *p1, sm_col *p2)
- {
- register sm_element *q1, *q2;
-
- q1 = p1->first_row;
- q2 = p2->first_row;
- while(q1 != 0 && q2 != 0) {
- if (q1->row_num != q2->row_num) {
- return q1->row_num - q2->row_num;
- }
- q1 = q1->next_row;
- q2 = q2->next_row;
- }
-
- if (q1 != 0) {
- return 1;
- } else if (q2 != 0) {
- return -1;
- } else {
- return 0;
- }
- }
-
-
- /*
- * return the intersection
- */
- sm_col *sm_col_and(sm_col *p1, sm_col *p2)
- {
- register sm_element *q1, *q2;
- register sm_col *result;
-
- result = sm_col_alloc();
- q1 = p1->first_row;
- q2 = p2->first_row;
- if (q1 == 0 || q2 == 0) return result;
- for(;;) {
- if (q1->row_num < q2->row_num) {
- if ((q1 = q1->next_row) == 0) {
- return result;
- }
- } else if (q1->row_num > q2->row_num) {
- if ((q2 = q2->next_row) == 0) {
- return result;
- }
- } else {
- (void) sm_col_insert(result, q1->row_num);
- if ((q1 = q1->next_row) == 0) {
- return result;
- }
- if ((q2 = q2->next_row) == 0) {
- return result;
- }
- }
- }
- }
-
- int sm_col_hash(sm_col *pcol, int modulus)
- {
- register int sum;
- register sm_element *p;
-
- sum = 0;
- for(p = pcol->first_row; p != 0; p = p->next_row) {
- sum = (sum*17 + p->row_num) % modulus;
- }
- return sum;
- }
-
- /*
- * remove an element from a col vector (given a pointer to the element)
- */
- void sm_col_remove_element(register sm_col *pcol, register sm_element *p)
- {
- dll_unlink(p, pcol->first_row, pcol->last_row,
- next_row, prev_row, pcol->length);
- sm_element_free(p);
- }
-
-
- void sm_col_print(FILE *fp, sm_col *pcol)
- {
- sm_element *p;
-
- for(p = pcol->first_row; p != 0; p = p->next_row) {
- (void) fprintf(fp, " %d", p->row_num);
- }
- }
-